package middleware

import (
	"strconv"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"gitlab-tech.shruisong.cn/growth/go-common/pkg/xmetrics"
)

const (
	handler = "base_gin_http"
)

var initEventTotal sync.Once

// MetricsNew 用来提供prometheus metrics
func MetricsNew() gin.HandlerFunc {
	s := []string{"handler", "code", "path", "method"}
	HTTPRequestTotal := &xmetrics.MetricsCounter{ // 构建Counter类型的metrics初始化数据
		Metrics: xmetrics.Metrics{
			Name:  "http_request_total",
			Help:  "How many HTTP requests processed,partitioned by status code and HTTP method.",
			Label: s,
		},
	}
	HTTPRequestTotal.NewCounterVec() // 初始化一个Counter类型的metric
	/*gauge样例
	HTTPRequest := &metrics.MetricsGauge{
		Metrics: metrics.Metrics{
			Name:  "basiclib_request",
			Help:  "a test example for gauge",
			Label: s,
		},
	}
	HTTPRequest.NewGaugeVec()
	*/

	// go HTTPRequestTotal.MetricsChanOut() // 新建协程异步消费metrics信息
	s = []string{"handler", "path", "method"}
	HTTPResponseTimeUs := &xmetrics.MetricsHistogram{
		Metrics: xmetrics.Metrics{
			Name:  "http_response_time_us",
			Help:  "How much time costs(us)",
			Label: s,
		},
		Buckets: prometheus.LinearBuckets(10000, 30000, 10),
	}
	HTTPResponseTimeUs.NewHistogramVec()
	ResponseSizeBytes := &xmetrics.MetricsHistogram{
		Metrics: xmetrics.Metrics{
			Name:  "http_response_size_bytes",
			Help:  "The size of http response",
			Label: s,
		},
		Buckets: prometheus.LinearBuckets(256, 256, 10),
	}
	ResponseSizeBytes.NewHistogramVec()
	RequestSizeBytes := &xmetrics.MetricsHistogram{
		Metrics: xmetrics.Metrics{
			Name:  "http_request_size_bytes",
			Help:  "The size of http request",
			Label: s,
		},
		Buckets: prometheus.LinearBuckets(256, 256, 10),
	}
	RequestSizeBytes.NewHistogramVec()

	return func(c *gin.Context) {
		requestCon := c.Request
		responseCon := c.Writer
		if requestCon.URL.Path == "/metrics" {
			c.Next()
			return
		}
		var headlen int
		for k, v := range requestCon.Header {
			headlen += len(k)
			for _, vv := range v {
				headlen += len(vv)
			}
		}
		requestSize := float64(c.Request.ContentLength) + float64(headlen)
		timeNow := time.Now()
		c.Next()
		label := []string{handler, strconv.Itoa(responseCon.Status()), requestCon.URL.Path, requestCon.Method}
		labelb := []string{handler, requestCon.URL.Path, requestCon.Method}
		HTTPRequestTotal.MetricsAdd(label, 1) // 往metric里面添加数据
		RequestSizeBytes.MetricsAdd(labelb, requestSize)
		ResponseSizeBytes.MetricsAdd(labelb, float64(responseCon.Size()))
		endTime := time.Since(timeNow)
		t := float64(endTime) / 1000
		HTTPResponseTimeUs.MetricsAdd(labelb, t)
		// defer func() {
		// 	fmt.Println("add HTTPRequestTotal counter")

		// 	//HTTPRequest.MetricsAdd(label, 1) //gauge样例使用
		// 	labelb := []string{handler, requestCon.URL.Path, requestCon.Method}

		// }()

		return

	}
}
